import { useWeb3ModalState } from '@web3modal/wagmi/vue';
import { getPublicClient, waitForTransaction, writeContract } from '@wagmi/core';
import contractABI from './abi/abi-market';
import { hexToBytes, formatBigIntToString } from '@/utils/utils';
import { getByNetworkId } from '@/api/market';
import { parseAbiItem, parseEther } from 'viem';
import { getNetwork } from "@wagmi/core";
import erc20ABI from './abi/erc20';
import { errorParse } from './error';
/**
 * 获取合约地址
 */
export async function getContractAddress() {
  const { selectedNetworkId } = useWeb3ModalState();
  console.log('selectedNetworkId', selectedNetworkId)
  const responseData = await getByNetworkId(selectedNetworkId);
  if (responseData.code != 200 || !responseData.data) {
    throw new Error('链Id:' + selectedNetworkId + '尚未配置合约地址');
  }
  const networkBean = responseData.data;
  if (!networkBean.marketContract) {
    throw new Error('链Id:' + selectedNetworkId + '尚未配置合约地址');
  }
  return networkBean.marketContract;
}
/**
 * erc20授权
 */
export async function erc20Approve(tokenAddress, value) {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: tokenAddress,
    abi: erc20ABI,
    chainId: Number(selectedNetworkId),
    functionName: 'approve',
    args: [contract, value]
  });
  const result = await waitForTransaction({ hash });
  return result;
}
/**
 * 获取当前已批准的erc20授权额度
 */
export async function allowanceERC20(tokenAddress, ownerAddress) {
  try {
    const contract = await getContractAddress();
    const { selectedNetworkId } = useWeb3ModalState();
    const publicClient = getPublicClient({
      chainId: Number(selectedNetworkId)
    });
    const data = await publicClient.readContract({
      address: tokenAddress,
      abi: erc20ABI,
      functionName: 'allowance',
      args: [ownerAddress, contract],
    });
    return data;
  } catch (error) {

  }

}

/**
 * 获取合约config
*/
export async function contractConfig() {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const publicClient = getPublicClient({
    chainId: Number(selectedNetworkId)
  });
  const data = await publicClient.readContract({
    address: contract,
    abi: contractABI,
    functionName: 'config',
  });
  return data;
}

/**
 * 创建offer
 */
export async function newOffer(params) {
  const { offerType, tokenId, amount, value, exToken, fullMatch } = params;

  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'newOffer',
    args: [offerType, hexToBytes(tokenId), formatBigIntToString(amount,18), formatBigIntToString(value,18), exToken, fullMatch]
  });
  const result = await waitForTransaction({ hash });
  return result;
}
/**
 * 创建offer
 */
export async function newOfferETH(params) {
  const { offerType, tokenId, amount, value, fullMatch, decimals } = params;

  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'newOfferETH',
    args: [offerType, hexToBytes(tokenId), formatBigIntToString(amount,18), formatBigIntToString(value,18), fullMatch],
    value: formatBigIntToString(value, decimals)
  });
  const result = await waitForTransaction({ hash });
  return result;
}
/**
 * 通过创建的Offer返回的tx查offerId
 */
export async function getPrizePoolDrawEventLogs(blockHeight, type) {
  let eventString = '';
  if (type == 'createOffer') {
    eventString = 'event NewOffer(uint256, uint8, bytes32, address, uint256, uint256, uint256, bool, address)'
  }
  if (type == 'createOrder') {
    eventString = 'event NewOrder(uint256, uint256, uint256, address, address)'
  }
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const publicClient = getPublicClient({
    chainId: Number(selectedNetworkId)
  });
  const data = await publicClient.getLogs({
    address: contract,
    event: parseAbiItem(eventString),
    fromBlock: blockHeight,
    toBlock: blockHeight,
  })
  return data
}



/**
 * 填充报价
 */
export async function fillOffer(params) {
  const { offerId, amount } = params;
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'fillOffer',
    args: [offerId, formatBigIntToString(amount,18)]
  });
  const result = await waitForTransaction({ hash });
  return result;
}
export async function fillOfferETH(params) {
  const { offerId, amount, value, decimals } = params;
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'fillOfferETH',
    args: [offerId, formatBigIntToString(amount,18)],
    value: formatBigIntToString(value,decimals)
  });
  const result = await waitForTransaction({ hash });
  return result;
}

/**
 * 取消报价
 */
export async function cancelOffer(offerId) {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'cancelOffer',
    args: [offerId]
  });
  const result = await waitForTransaction({ hash });
  return result;
}

/**
 * 结算订单
 */
export async function settleFilled() {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'settleFilled',
    args: [offerId]
  });
  const result = await waitForTransaction({ hash });
  return { result };
}
/**
 * 取消结算订单
 */
export async function settleCancelled(orderId) {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'settleCancelled',
    args: [orderId]
  });
  const result = await waitForTransaction({ hash });
  return result;
}

/**
 * 批量结算订单
 */
export async function settleFilleds(orderIds) {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const { hash } = await writeContract({
    address: contract,
    abi: contractABI,
    chainId: Number(selectedNetworkId),
    functionName: 'settleFilleds',
    args: [orderIds]
  });
  const result = await waitForTransaction({ hash });
  return result;
}

/**
 * 订单结算
 */
// export async function settle2Steps() {
//   const contract = await getContractAddress();
//   const { selectedNetworkId } = useWeb3ModalState();
//   const { hash } = await writeContract({
//     address: contract,
//     abi: contractABI,
//     chainId: Number(selectedNetworkId),
//     functionName: 'settle2Steps',
//     args: [orderId, hexToBytes(hash)]
//   });
//   const result = await waitForTransaction({ hash });
//   return result;
// }

/**
 * 获取指定报价中代币的总数量
 */
export async function offerAmount() {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const publicClient = getPublicClient({
    chainId: Number(selectedNetworkId)
  });
  const data = await publicClient.readContract({
    address: contract,
    abi: contractABI,
    functionName: 'offerAmount',
    args: [offerId]
  });
  return data;
}

/**
 * 获取指定报价中尚未被接受的代币的数量
 */
export async function offerAmountAvailable() {
  const contract = await getContractAddress();
  const { selectedNetworkId } = useWeb3ModalState();
  const publicClient = getPublicClient({
    chainId: Number(selectedNetworkId)
  });
  const data = await publicClient.readContract({
    address: contract,
    abi: contractABI,
    functionName: 'offerAmountAvailable',
    args: [offerId]
  });
  return data;
}

